package xxx.yyy.zzz.movie;

import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * https://www.1905.com/mdb/film/2244288/performer/
 */
public class MoviePerformerProcessor implements PageProcessor {
    private static final Logger log = LoggerFactory.getLogger(MoviePerformerProcessor.class);

    // 抓取网站的相关配置，包括：编码、抓取间隔、重试次数等
    private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);

    private String url;

    private Movie movie;

    private static final String BASE_URL = "https://www.1905.com/mdb/film/%s/performer/";
    private static final String DIRECTOR = "导演";
    private static final String Writer = "编剧";
    private static final String Actor = "演员";

    public MoviePerformerProcessor(Integer movieId, Movie movie) {
        Objects.requireNonNull(movieId);
        this.url = Strings.formatIfArgs(BASE_URL, movieId);
        this.movie = movie;
    }

    @Override
    public void process(Page page) {
        List<Selectable> list = page.getHtml().css("section>div>div.secPage-actors").nodes();

        for (Selectable selectable : list) {
            if (isDirectorSection(selectable)) {
                log.debug("获取导演信息");
                movie.setActors(getPerformer(selectable));
            }
            else if (isWriterSection(selectable)) {
                log.debug("获取编剧信息");
                movie.setWriters(getPerformer(selectable));
            }
            else if (isActorSection(selectable)) {
                log.debug("获取演员信息");
                movie.setActors(getPerformer(selectable));
            }
            else {
                throw new UnsupportedOperationException();
            }
        }
    }

    @Override
    public Site getSite() {
        return site;
    }

    public String getUrl() {
        return Objects.requireNonNull(url);
    }

    private boolean isDirectorSection(Selectable selectable) {
        Objects.requireNonNull(selectable);

        List<Selectable> list = selectable.css("h3.title-style-common").nodes();
        if (list.size() == 0)
            return false;

        for (Selectable s : list) {
            String h3Content = s.xpath("//h3/text()").get();
            if ("导演".equals(h3Content))
                return true;
        }

        return false;
    }

    private boolean isWriterSection(Selectable selectable) {
        Objects.requireNonNull(selectable);

        List<Selectable> list = selectable.css("h3.title-style-common").nodes();
        if (list.size() == 0)
            return false;

        for (Selectable s : list) {
            String h3Content = s.xpath("//h3/text()").get();
            if ("编剧".equals(h3Content))
                return true;
        }

        return false;
    }

    private boolean isActorSection(Selectable selectable) {
        Objects.requireNonNull(selectable);

        List<Selectable> list = selectable.css("h3.title-style-common").nodes();
        if (list.size() == 0)
            return false;

        for (Selectable s : list) {
            String h3Content = s.xpath("//h3/text()").get();
            if ("演员".equals(h3Content))
                return true;
        }

        return false;
    }

    private List<String> getPerformer(Selectable selectable) {
        ArrayList<String> performers = new ArrayList<>(2);
        List<Selectable> list = selectable.css("a.left-actor").nodes();

        for (Selectable s : list) {
            String content = s.xpath("//a/text()").get();
            content = content.replaceAll("\\u00A0"," ");
            for (String token : StringUtils.split(content, " ")) {
                performers.add(StringUtils.trim(token));
            }
        }

        return performers;
    }
}
